<script setup lang="ts" name="StrEdit">
import MenuBar from '@/views/components/menuBar/index.vue'
import md5 from 'crypto-js/md5';
import { createUUID } from '@/utils/ruoyi.js'
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
import StrReplace from './components/strReplace/index.vue'
import StrInsert from './components/strInsert/index.vue'
import CreateUUID from './components/createUUID/index.vue'
import CreateTimeStamp from './components/createTimeStamp/index.vue'
import { formateJson } from './components/index'
import { format as formatSql } from 'sql-formatter'
/*========================================>( 模型属性 )<========================================*/
//窗口文本内容
const textarea = ref<string>('')
//是否改变过大小写
const isUpperCase = ref<boolean>(false)
//是否显示替换设置框
const showReplaceModal = ref<boolean>(false)
//是否显示插入设置框
const showInsertModal = ref<boolean>(false)
//是否显示插入UUID框
const showUUIDModal = ref<boolean>(false)
//是否显示插入tamp框
const showTimestampModal = ref<boolean>(false)
//切换16或32
const uuidFlag = ref<boolean>(false)
//历史内容记录
const textareaHistory = ref<Array<string>>([])
//是否保存下一次的内容变化记录
const historyLock = ref<boolean>(false)


/*========================================>( 计算属性 )<========================================*/
//计算内容行数
const textareaRowNum = computed(() => {
    let str = textarea.value
    let value = ''
    str = str.replace(/\r/gi, '')
    const strs = str.split('\n')
    let n = strs.length;
    for (let i = 1; i <= n; i++) {
        value += i + '\n';
    }
    return value
})
//计算内容字符串长度
const textareaLength = computed(() => {
    return textarea.value.trim().length
})
//每一行的内容
const lineList = computed(() => {
    let str = textarea.value.replace(/\r/gi, '')
    return str.split('\n')
})

/*========================================>( 属性监听 )<========================================*/
//监听符合条件的改变保存为记录
watch(textarea, (n, o) => {
    if (historyLock.value) {
        historyLock.value = false
        return
    }
    if (o) {
        textareaHistory.value.push(o)
    }
})

/*========================================>( 监听方法 )<========================================*/
//复制窗口内容
const handleCopyTextarea = () => {
    window.ipcRenderer.send('GENERAL-CLIPBOARD', { type: 'text', value: textarea.value })
    proxy?.$modal.notifySuccess('已复制到剪贴板')
}
//清除窗口内容
const handleClearTextarea = () => {
    textarea.value = ''
}
//撤销操作
const handleBackHistory = () => {
    if (textareaHistory.value.length) {
        historyLock.value = true
        let hislist = []
        for (const [index, his] of textareaHistory.value.entries()) {
            if (index == textareaHistory.value.length - 1) {
                textarea.value = textareaHistory.value[index]
                continue
            }
            hislist.push(his)
        }
        textareaHistory.value = hislist
    }
}

//监听操作
const handleOperate = (mark: string) => {
    if (!textarea.value.length) {
        proxy?.$modal.alertError("请先输入字符");
        return
    }
    switch (mark) {
        case 'RemoveSpace':
            textarea.value = textarea.value.trim()
            proxy?.$modal.notifySuccess('去除成功')
            break
        case 'RemoveSpaceAll':
            textarea.value = textarea.value.replaceAll(' ', '')
            proxy?.$modal.notifySuccess('去除成功')
            break
        case 'ChangeCase':
            textarea.value = isUpperCase.value ? textarea.value.toLowerCase() : textarea.value.toUpperCase()
            isUpperCase.value = !isUpperCase.value
            proxy?.$modal.notifySuccess('转换成功')
            break
        case 'Replace':
            showReplaceModal.value = true
            break
        case 'Insert':
            showInsertModal.value = true
            break
        case 'TrimEnter':
            textarea.value = textarea.value.replaceAll(/\r/gi, '')
            textarea.value = textarea.value.replaceAll('\n', '')
            proxy?.$modal.notifySuccess('缩进成功')
            break
        case 'Sql':
            textarea.value = formatSql(textarea.value)
            break
        case 'Json':
            var result = formateJson(textarea.value)
            if (result) textarea.value = result
            break
    }
}
const handleCode = (mark: string) => {
    if (!textarea.value.trim().length) {
        proxy?.$modal.alertError('请先输入字符')
        return
    }
    switch (mark) {
        case 'MD5':
            textarea.value = md5(textarea.value).toString()
            break
        case 'UrlEncode':
            textarea.value = encodeURIComponent(textarea.value)
            break
        case 'UrlDecode':
            textarea.value = decodeURIComponent(textarea.value)
            break
    }
}
const handleCreate = (mark: string) => {
    switch (mark) {
        case 'UUID':
            uuidFlag.value = !uuidFlag.value
            textarea.value += (textarea.value ? '\n' : '') + createUUID(uuidFlag.value ? 32 : 16)
            break
        case 'uuidCreate':
            showUUIDModal.value = true
            break
        case 'Timestamp':
            textarea.value += (textarea.value ? '\n' : '') + new Date().getTime()
            break
        case 'TimestampDesign':
            showTimestampModal.value = true
            break
        case 'TimestampToDate':
            var min = new Date('1-01-01 00:00:00').getTime()
            var max = new Date('3000-12-31 23:59:59').getTime()
            var afterList = []
            for (const line of lineList.value) {
                if (! /^\d+$/.test(line) || Number(line) < min || Number(line) > max) {
                    afterList.push(line)
                    continue
                }
                const date = new Date(Number(line))
                const month = (date.getMonth() + 1) < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1)
                const dateStr = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
                const hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
                const minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
                const seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
                const lineAfter = date.getFullYear() + '-' + month + '-' + dateStr + ' ' + hours + ':' + minutes + ':' + seconds
                afterList.push(lineAfter)
            }
            textarea.value = afterList.join('\n')
            proxy?.$modal.notifySuccess('解析时间戳成功')
            break
    }
}

//监听替换的面泛返回
const handleReplaceOrInsertModalBack = (res: any) => {
    const { result, keep } = res
    if (result) textarea.value = result
    if (!keep) {
        showReplaceModal.value = false
        showInsertModal.value = false
    }
}

const handleUuidAndModalBack = (res: any) => {
    const { result, keep } = res
    if (result) textarea.value += (textarea.value.length ? '\n' : '') + result
    if (!keep) {
        showUUIDModal.value = false
        showTimestampModal.value = false
    }
}

</script>
<template>
    <MenuBar title="字符串工厂" mid="ModuleStrEdit"/>
    <div class="main-content str-edit">
        <div class="title">请将要处理的字符串粘贴入文本框内
            <div class="btn copy-btn" @click="handleCopyTextarea">
                <svg-icon icon-class="copy" width="16" height="16" />
                复制
            </div>
            <div class="btn clear-btn" @click="handleClearTextarea">
                <svg-icon icon-class="clear" width="16" height="16" />
                清空
            </div>
            <div class="btn cancel-btn" @click="handleBackHistory">
                <svg-icon icon-class="delete" width="16" height="16" />
                撤销
            </div>
        </div>
        <div class="str-pad">
            <el-input id="strpad1" class="row-num" type="textarea" :rows="10" disabled v-model="textareaRowNum"
                spellcheck="false" onscroll="document.getElementById('strpad2').scrollTop = this.scrollTop;">
            </el-input>
            <el-input id="strpad2" class="value" type="textarea" :rows="10" placeholder="请输入文本内容" v-model="textarea"
                clearable autofocus spellcheck="false"
                onscroll="document.getElementById('strpad1').scrollTop = this.scrollTop;">
            </el-input>
        </div>
        <div class="str-length"><i class="el-icon-s-claim"></i>有效文本长度：{{ textareaLength }}</div>
        <el-divider content-position="left"><el-icon>
                <Tools />
            </el-icon> 常用</el-divider>
        <div>
            <el-button @click="handleOperate('RemoveSpace')">去前后空格</el-button>
            <el-button @click="handleOperate('RemoveSpaceAll')">去所有空格</el-button>
            <el-button @click="handleOperate('ChangeCase')">转换大小写</el-button>
            <el-button @click="handleOperate('Replace')">条件替换</el-button>
            <el-button @click="handleOperate('Insert')">条件插入</el-button>
            <el-button @click="handleOperate('TrimEnter')">缩进</el-button>
        </div>
        <el-divider content-position="left"><el-icon>
                <Grid />
            </el-icon> 编码 / 解码</el-divider>
        <div>
            <el-button @click="handleCode('MD5')">MD5加密</el-button>
            <el-button @click="handleCode('UrlEncode')">UrlEncode编码</el-button>
            <el-button @click="handleCode('UrlDecode')">UrlDecode解码</el-button>
        </div>
        <el-divider content-position="left"><el-icon>
                <Promotion />
            </el-icon> 生成 / 解析</el-divider>
        <div>
            <el-button @click="handleCreate('UUID')">随机UUID</el-button>
            <el-button @click="handleCreate('uuidCreate')">定制UUID</el-button>
            <el-button @click="handleCreate('Timestamp')">实时时间戳</el-button>
            <el-button @click="handleCreate('TimestampDesign')">指定时间戳</el-button>
            <el-button @click="handleCreate('TimestampToDate')">解析时间戳</el-button>
        </div>
        <el-divider content-position="left"><el-icon>
                <MagicStick />
            </el-icon> 美化</el-divider>
        <div>
            <el-button @click="handleOperate('Sql')">美化SQL</el-button>
            <el-button @click="handleOperate('Json')">美化JSON</el-button>
        </div>
        <StrReplace v-if="showReplaceModal" :content="textarea" @back="handleReplaceOrInsertModalBack" />
        <StrInsert v-if="showInsertModal" :content="textarea" @back="handleReplaceOrInsertModalBack" />
        <CreateUUID v-if="showUUIDModal" @back="handleUuidAndModalBack" />
        <CreateTimeStamp v-if="showTimestampModal" @back="handleUuidAndModalBack" />
    </div>
</template>
<style lang="scss">
.main-content.str-edit {
    width: 100%;
    height: calc(100% - 40px);
    padding: 0 5px;

    .title {
        color: #666;
        padding: 10px 0 10px 0;

        .btn {
            width: 70px;
            height: 25px;
            line-height: 25px;
            text-align: center;
            color: #fff;
            float: right;
            font-size: 13px;
            cursor: pointer;
            margin-right: 5px;

            &:hover {
                color: #ccc;
            }
        }

        .copy-btn {
            background-color: #0099CC;
        }

        .clear-btn {
            background-color: #FF9900;
        }

        .cancel-btn {
            background-color: #FF6666;
        }

        .auto-close-btn {
            width: 100px;
            background-color: #999;
            color: #ccc;

            &.active {
                background-color: #99CC66;
                color: #fff;
            }
        }
    }

    .str-pad {
        width: 100%;
        height: 300px;
        background-color: rgba(0, 0, 0, 0.1);
        display: flex;
        flex-direction: row;
        box-sizing: border-box;
        border: solid 1px #000;

        .el-textarea__inner {
            resize: none;
            outline: none;
            border: 0;
            border-radius: 0;
            background: #f5f7fa;
            box-sizing: border-box;
            height: 298px;
        }

        .row-num {
            width: 55px;
            float: left;
            padding-left: 0;
            overflow-x: hidden;
            box-sizing: border-box;

            .el-textarea__inner {
                padding-left: 0;
                text-align: right;
                overflow-x: hidden;
                background-color: #666;
                border-right: solid 1px #000;
                color: #fff;
                box-sizing: border-box;

                &::-webkit-scrollbar {
                    display: none;
                }
            }
        }

        .value {
            float: left;
        }
    }

    .str-length {
        font-size: 14px;
        font-weight: bold;
        text-align: right;
        color: #003366;
        padding: 0 10px 0 0;
    }

    .el-divider__text {
        font-size: 15px;
        font-weight: bold;
    }

    .el-button {
        margin-top: 8px;
        display: inline-block
    }

    .el-dialog__body {
        padding-top: 5px;
        padding-bottom: 0;
    }

}
</style>
<style lang="scss" scoped></style>